package com.locationtracker.plus.ui.fragment.map

import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.viewModels
import com.blankj.utilcode.constant.TimeConstants
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.*
import com.locationtracker.plus.R
import com.locationtracker.plus.app.base.BaseFragment
import com.locationtracker.plus.app.weight.datetimepicker.DateTimePicker
import com.locationtracker.plus.databinding.FragmentMapLocationBinding
import com.locationtracker.plus.viewmodel.request.RequestMemberViewModel
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.util.dp2px
import me.hgj.jetpackmvvm.ext.util.notNull
import java.util.*

class LocationFragment : BaseFragment<BaseViewModel, FragmentMapLocationBinding>() {

    private var friendId: String? = null

    private lateinit var mMap: GoogleMap

    private var startTime: String
    private var endTime: String

    private val requestMemberViewModel by viewModels<RequestMemberViewModel>()

    override fun initView(savedInstanceState: Bundle?) {
        friendId = arguments?.getString("friendId")
        mDatabind.click = ProxyClick()
        mDatabind.includeHeader.headerBack.setOnClickListener { nav().navigateUp() }
        mDatabind.locationStartTime.text = startTime
        mDatabind.locationEndTime.text = endTime

        (childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment).getMapAsync { p0 ->
            mMap = p0
            addMarker()
        }
    }

    override fun lazyLoadData() {
        friendId.notNull(
            { requestMemberViewModel.friendRoute(it, startTime, endTime) },
            { requestMemberViewModel.myRoute(startTime, endTime) }
        )
    }

    override fun createObserver() {
        requestMemberViewModel.routeList.observe(viewLifecycleOwner) {
            if (it.isNullOrEmpty()) {
                ToastUtils.showLong("There are no track records for this time period")
                return@observe
            }
            addMarker()
        }
    }

    private fun addMarker() {
        if (!::mMap.isInitialized || requestMemberViewModel.routeList.value.isNullOrEmpty()) {
            return
        }
        val latLngBounds = LatLngBounds.Builder()
        val polylineOptions = PolylineOptions()
            .color(Color.parseColor("#1FD08C"))
            .startCap(RoundCap())
            .endCap(RoundCap())
        requestMemberViewModel.routeList.value?.filter {
            it.coordinate.contains(",")
        }?.apply {
            forEachIndexed { index, routeLocation ->
                val latLng = LatLng(
                    routeLocation.coordinate.split(",")[0].toDouble(),
                    routeLocation.coordinate.split(",")[1].toDouble()
                )
                latLngBounds.include(latLng)
                polylineOptions.add(latLng)
                mMap.addMarker(
                    MarkerOptions()
                        .position(latLng)
                        .title(routeLocation.address)
                        .snippet(routeLocation.date)
                        .anchor(0.5f, 0.5f)
                        .icon(
                            BitmapDescriptorFactory.fromResource(
                                when (index) {
                                    0 -> R.mipmap.start_dot
                                    size - 1 -> R.mipmap.end_dot
                                    else -> R.mipmap.middle_dot
                                }
                            )
                        )
                )
                mMap.addPolyline(polylineOptions)
                mMap.animateCamera(
                    CameraUpdateFactory.newLatLngBounds(
                        latLngBounds.build(),
                        mActivity.dp2px(20)
                    )
                )
            }
        }
    }

    inner class ProxyClick {
        fun start() {
            showDateTimePicker(0)
        }

        fun end() {
            showDateTimePicker(1)
        }

        fun submit() {
            if (TimeUtils.string2Date(startTime, "yyyy-MM-dd HH:mm")
                    .before(TimeUtils.string2Date(endTime, "yyyy-MM-dd HH:mm"))
            ) {
                mMap.clear()
                friendId.notNull(
                    { requestMemberViewModel.friendRoute(it, startTime, endTime) },
                    { requestMemberViewModel.myRoute(startTime, endTime) }
                )
            } else {
                ToastUtils.showShort("From time must be earlier than to time")
            }
        }
    }

    /**
     * @param type 0:StartTime 1:EndTime
     */
    fun showDateTimePicker(type: Int) {
        val date = if (type == 0) TimeUtils.string2Date(startTime, "yyyy-MM-dd HH:mm")
        else TimeUtils.string2Date(endTime, "yyyy-MM-dd HH:mm")
        DateTimePicker.Builder(mActivity)
            .onDateTimeSetListener { year, month, dayOfMonth, hourOfDay, minute ->
                val calendar = Calendar.getInstance()
                calendar.set(year, month, dayOfMonth, hourOfDay, minute)
                if (type == 0) {
                    startTime = TimeUtils.date2String(calendar.time, "yyyy-MM-dd HH:mm")
                    mDatabind.locationStartTime.text = startTime
                }
                if (type == 1) {
                    endTime = TimeUtils.date2String(calendar.time, "yyyy-MM-dd HH:mm")
                    mDatabind.locationEndTime.text = endTime
                }
            }
            .initialValues(Calendar.getInstance().apply { time = date })
            .build()
            .show()
    }

    init {
        val current = Calendar.getInstance().timeInMillis
        startTime = TimeUtils.millis2String(current - TimeConstants.DAY, "yyyy-MM-dd HH:mm")
        endTime = TimeUtils.millis2String(current, "yyyy-MM-dd HH:mm")
    }
}